package com.chr.hongyun.config.shiro;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@Slf4j
public class JwtUtil {

    @Value("${hongyun.jwt.secret}")
    private String secret;

    @Value("${hongyun.jwt.expire}")
    private int expire;

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 员工登录或注册结束根据员工Id和密钥生成令牌字符串
     * @param userId 员工Id
     * @return
     */
    public String createToken(int userId) {
        //创建token,token由二部分构成,第一部分为加密的密钥,第二部分是员工Id
        //Date date = DateUtil.offset(new Date(), DateField.DAY_OF_YEAR, 5);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTCreator.Builder builder = JWT.create();
        String token = builder.withClaim("userId", userId).sign(algorithm);
        return token;
    }

    /**
     * 根据令牌字符串获取员工Id
     * @param token 令牌字符串
     * @return
     */
    public int getUserId(String token) {
        DecodedJWT jwt = JWT.decode(token);
        Integer userId = jwt.getClaim("userId").asInt();
        return userId;
    }

    /**
     * 登录后验证token是否有效
     * @param token
     */
    public void verifierToken(String token) {
        Algorithm algorithm = Algorithm.HMAC256(secret);
        JWTVerifier verifier = JWT.require(algorithm).build();
        verifier.verify(token);
        int userId = getUserId(token);
        if (!redisTemplate.hasKey(userId + "")) throw new TokenExpiredException("缓存令牌已失效");
    }
}
